package com.itheima.reggie.filter;

import com.alibaba.fastjson.JSON;
import com.itheima.reggie.common.R;
import com.itheima.reggie.common.SessionThreadLocal;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@Slf4j
@WebFilter(urlPatterns = "/*")
public class RequestFilter implements Filter {
    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    private static String[] outFilter = new String[]{
            "/backend/**",
            "/common/**",
            "/front/**",
            "/employee/login",
            "/employee/logout",
            "/user/sendMsg",
            "/user/login",
            "/doc.html",
            "/webjars/**",
            "/swagger-resources",
            "/v2/api-docs"

    };

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //将通用请求换为http请求
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;


        //获取请求URI
        String requestURI = req.getRequestURI();

        log.info("过滤路径：{}",requestURI);

        //拿到是否需要过滤
        boolean flag = checkURI(requestURI);

        //不需要过滤
        if (!flag){
            chain.doFilter(req, resp);
            return;
        }
        //需要过滤
        HttpSession session = req.getSession();

        //当域中有值时(处于登录状态)服务端
        if(session.getAttribute("employee") != null){

            //在放行之前将session域中数据存入 ThreadLocal 中
            Long id = (Long) req.getSession().getAttribute("employee");
            SessionThreadLocal.setThreadLocal(id);

            chain.doFilter(req, resp);//放行

            //为了栈溢出，我们需要将使用完毕的ThreadLocal清空
            //此时，响应又会再次回到过滤器，可以顺便再将使用完毕的ThreadLocal清空
            SessionThreadLocal.removeThreadLocal();

            return;
        }

        //当域中有值时(处于登录状态)客户端
        if(session.getAttribute("user") != null){

            //在放行之前将session域中数据存入 ThreadLocal 中
            Long id = (Long) req.getSession().getAttribute("user");
            SessionThreadLocal.setThreadLocal(id);

            chain.doFilter(req, resp);//放行

            //为了栈溢出，我们需要将使用完毕的ThreadLocal清空
            //此时，响应又会再次回到过滤器，可以顺便再将使用完毕的ThreadLocal清空
            SessionThreadLocal.removeThreadLocal();

            return;
        }

        //当域中没有值时
        if (session.getAttribute("employee") == null){
            resp.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));
        }


    }

    /**
     * 校验是否需要过滤
     * @param requestURI
     * @return false：不需要 true：需要
     */
    private boolean checkURI(String requestURI) {
        for (String s : outFilter) {
            if (antPathMatcher.match(s,requestURI)){
                return false;
            }
        }
        return true;
    }
}
